using System.Data.SqlClient;
using Microsoft.Vsts.Ranger.Migration.TfsToTfs.Service.Common;
using Microsoft.Vsts.Ranger.Migration.TfsToTfs.Service.Schemas;
using Microsoft.Vsts.Ranger.Migration.TfsToTfs.Service.Schemas.SessionsDatasetTableAdapters;

namespace Microsoft.Vsts.Ranger.Migration.TfsToTfs.Service.Data
{
    public class EventData
    {
        public EventData()
        {
            _timeSinceFlush = System.DateTime.Now;
        }
        private SessionsDataset _ds = new SessionsDataset();
        private System.DateTime _timeSinceFlush;

        private string ConnectString
        {
            get
            {
                return System.Configuration.ConfigurationManager.ConnectionStrings["TfsMigrationService.Properties.Settings.TPCopyLoggingConnectionString"].ConnectionString;
            }
        }

        public void GetSessionInstances(SessionsDataset ds, bool includeCompleted)
        {
            SessionInstancesTableAdapter adapter = new SessionInstancesTableAdapter();
            adapter.Connection.ConnectionString = this.ConnectString;

            adapter.Fill(ds.SessionInstances, includeCompleted);
        }

        public void GetSessionInstanceEvents(SessionsDataset ds, int sessionInstanceID)
        {
            EventsTableAdapter adapter = new EventsTableAdapter();
            adapter.Connection.ConnectionString = this.ConnectString;

            adapter.Fill(ds.Events,sessionInstanceID);
        }

        public int InsertSessionInstanceRow(string sessionId, bool oneTimeOnly, bool oneWayMigration)
        {
            SessionInstancesTableAdapter adapter = new SessionInstancesTableAdapter();
            adapter.Connection.ConnectionString = this.ConnectString;

            int? returnVal = -1;

            adapter.sp_InsertSessionInstance(SessionInstanceStatuses.Running.ToString(), System.DateTime.Now, sessionId, oneTimeOnly, oneWayMigration, ref returnVal);

            if(returnVal.HasValue) 
                return returnVal.Value;
            else
                throw new Microsoft.TeamFoundation.Migration.Toolkit.MigrationException("SessionInstanceID was not acquired.");

        }

        public void UpdateSessionInstance(int sessionInstanceId, string currentStatus)
        {
            SessionInstancesTableAdapter adapter = new SessionInstancesTableAdapter();
            adapter.Connection.ConnectionString = this.ConnectString;

            adapter.sp_UpdateSessionInstance(sessionInstanceId, currentStatus);
        }

        public SessionsDataset.EventsRow GetNewRow()
        {
            return _ds.Events.NewEventsRow();
        }

        public void StoreEventRow(SessionsDataset.EventsRow row)
        {
            lock (_ds)
            {
                _ds.Events.AddEventsRow(row);

                if (System.DateTime.Now > this._timeSinceFlush.AddSeconds(3))
                {
                    FlushDB();
                    _timeSinceFlush = System.DateTime.Now;
                }
            }
        }

        private void FlushDB()
        {
            SqlBulkCopy bcp = new SqlBulkCopy(this.ConnectString);

            bcp.DestinationTableName = "Events";
            bcp.WriteToServer(this._ds.Events);
            this._ds.Events.Clear();
            this._ds.AcceptChanges();
        }

    }
}
